package org.snia.server.service;

import java.util.Map;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.snia.cdmi.ErrorCodes;
import org.snia.cdmi.auth.Principal;
import org.snia.cdmi.exception.BadRequestException;
import org.snia.cdmi.exception.ConflictException;
import org.snia.cdmi.exception.ForbiddenException;
import org.snia.cdmi.exception.InternalException;
import org.snia.cdmi.exception.NotFoundException;
import org.snia.cdmi.locator.KetamaNodeLocator;
import org.snia.cdmi.locator.Node;
import org.snia.cdmi.model.AccessControlList;
import org.snia.cdmi.model.Container;
import org.snia.cdmi.model.ContainerProperties;
import org.snia.cdmi.model.ContainerStatus;
import org.snia.cdmi.model.MetaContainer;
import org.snia.exception.BusinessException;
import org.snia.server.ejb.cache.CacheOperation;
import org.snia.server.ejb.container.ContainerOperation;
import org.snia.server.ejb.container.LocalContainerOperation;
import org.snia.server.model.cache.ContainerCache;

public class ContainerService {
	private static Log log = LogFactory.getLog(ContainerService.class);
	private Principal principal;
	
	private static int MODE = 0;//从配置文件中读取。
	//MODE = 0: 表示单机版。
	//MODE = 1: 表示系统中无独立的缓存服务器，元数据和缓存服务器都放置与执行服务器中。
	//MODE = 2 ：表示系统中存在多台缓存服务器，元数据分散与执行服务本地磁盘中，但缓存服务器独立。
	//MODE = 3: 表示元数据存储于独立共享存储，但缓存分散在执行服务器集群。
	//MODE = 4: 表示元数据存储于独立存储中，缓存存在多台缓存服务器中，均与执行服务器分离。
	private InitialContext ctx = null; 
	private CacheOperation cache_remote = null;
	private ContainerOperation remote = null;
	private LocalContainerOperation local = null;
	
	public ContainerService(Principal principal){
		this.principal = principal;
	}
	
	public void createContainer(Container container) throws BusinessException{
		
		
		//检查参数
		if(container == null || container.getName() == null){
			throw new BadRequestException(ErrorCodes.InvalidArgument);
		}
		
		ContainerCache cache = null;
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
		
		if(MODE == 0){			//表示单机版
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
//				local = new ContainerBean();
				local.createContainer(container, principal);
			} catch (NamingException e1) {
				log.error(e1.getMessage());
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 1){	//缓存与元数据分散到执行服务器集群上
			Node node = KetamaNodeLocator.getLocator().getPrimary(container.getName());
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				remote.createContainer(container, principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
//			this.createContainer(container, node.getHost());
			
		}else if(MODE == 2){	//独立缓存集群，元数据分散在执行服务器的本地磁盘。
			
			//1.检查集群中是否存在与新建的容器名相同的缓存对象
			//2.缓存不存在，继续检查指定存储位置上的容器元数据文件是否存在
			//3.如果容器的元数据文件不存在，则创建新的元数据文件
			//4.将创建的新容器放入到缓存中
			Node node = KetamaNodeLocator.getCacheLocator().getPrimary(container.getName());
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(container.getName());
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
			
			if(cache == null){
				node = KetamaNodeLocator.getLocator().getPrimary(container.getName());
				pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
				try {
					ctx = new InitialContext(pros);
					remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				} catch (NamingException e) {
					throw new InternalException(ErrorCodes.InternalError);
				}
				
				if(remote.exist(container.getName())){
					//容器已经存在，抛出异常
					throw new ConflictException(ErrorCodes.ContainerAlreadyExists);
				}
				//创建新容器的元数据信息
				remote.createMetaContainer(container);
				
				//将创建的新容器放入到缓存中
				cache = new ContainerCache(container.getName());
//					cache_service.putCache(cache, node.getHost());
				cache_remote.putCache(container.getName(), cache, 0);
			}else{
				//要创建的容器名在缓存中已存在，则不允许创建
				throw new ConflictException(ErrorCodes.ContainerAlreadyExists);
			}
		}else if(MODE == 3){	//元数据使用独立共享存储，缓存分散到各个执行服务器集群
			Node node = KetamaNodeLocator.getLocator().getPrimary(container.getName());
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(container.getName());

				if(cache == null){
					ctx = new InitialContext();
					local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
					
					if(local.exist(container.getName())){
						//容器已经存在，抛出异常
						throw new ConflictException(ErrorCodes.ContainerAlreadyExists);
					}
					//创建新容器的元数据信息
					local.createMetaContainer(container);
					//将创建的新容器放入到缓存中
					cache = new ContainerCache(container.getName());
					cache_remote.putCache(container.getName(), cache, 0);
				}else{
					//要创建的容器名在缓存中已存在，则不允许创建
					throw new ConflictException(ErrorCodes.ContainerAlreadyExists);
				}
			} catch (NamingException e) {
				e.printStackTrace();
			}
		}else if(MODE == 4){	//元数据使用独立存储，缓存存在多台缓存服务器中，均与执行服务器分离。
			Node node = KetamaNodeLocator.getCacheLocator().getPrimary(container.getName());
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(container.getName());

				if(cache == null){
					ctx = new InitialContext();
					local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
					if(local.exist(container.getName())){
						//容器已经存在，抛出异常
						throw new ConflictException(ErrorCodes.ContainerAlreadyExists);
					}
					//创建新容器的元数据信息
					local.createMetaContainer(container);
					//将创建的新容器放入到缓存中
					cache = new ContainerCache(container.getName());
					cache_remote.putCache(container.getName(), cache, 0);
				}else{
					//要创建的容器名在缓存中已存在，则不允许创建
					throw new ConflictException(ErrorCodes.ContainerAlreadyExists);
				}
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else {
			//TODO 系统配置有错误，告警，并生成日志
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	
	public void deleteContainer(String name) throws BusinessException{
		//检查参数
		if(name == null || name.trim().length() < 1){
			throw new BadRequestException(ErrorCodes.InvalidArgument);
		}
		
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
		
		ContainerCache cache = null;
		if(MODE == 0){			//表示单机版
			
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
//				local = new ContainerBean();
				local.deleteContainer(name, this.principal);
			} catch (NamingException e1) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 1){	//缓存与元数据分散到执行服务器集群上
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				remote.deleteContainer(name, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 2){	//独立缓存集群，元数据分散在执行服务器的本地磁盘。
			Node cache_node = KetamaNodeLocator.getCacheLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", cache_node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
			
			if(cache != null){
				if(cache.getStatus() != ContainerStatus.Working.getValue()){
					//只有容器状态为正常时，才能进行容器的删除，否则返回409.冲突
					throw new ForbiddenException(ErrorCodes.OperationAborted);
				}
			}
			
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			MetaContainer metafile = null;
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				metafile = remote.getMetaContainer(name);
			} catch (NamingException e) {
				// TODO Auto-generated catch block
				throw new InternalException(ErrorCodes.InternalError);
			}
			if(metafile != null){
				if(metafile.getStatus() != ContainerStatus.Working.getValue()){
					throw new ForbiddenException(ErrorCodes.OperationAborted);
				}
			}else{
				throw new NotFoundException(ErrorCodes.NoSuchContainer);
			}
			
			//更新容器元数据文件中的容器状态
			metafile.setStatus(ContainerStatus.Releasing.getValue());
			remote.updateMetaContainer(metafile.getUuid(), metafile);
			
			//如果存在缓存，则更新缓存状态。
			if(cache != null){
				cache.setStatus(ContainerStatus.Releasing.getValue());
				cache_remote.updateCache(name, cache);
			}else{
//				TODO 缓存不存在，添加到缓存
			}
			//TODO 容器存在，写入删除容器任务到临时任务表中
			
		}else if(MODE == 3){	//元数据使用独立共享存储，缓存分散到各个执行服务器集群
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			MetaContainer metafile = null;
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
				if(cache != null){
					if(cache.getStatus() != ContainerStatus.Working.getValue()){
						//只有容器状态为正常时，才能进行容器的删除，否则返回409.冲突
						throw new ForbiddenException(ErrorCodes.OperationAborted);
					}
				}
				
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				metafile = local.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}

			if(metafile != null){
				if(metafile.getStatus() != ContainerStatus.Working.getValue()){
					throw new ForbiddenException(ErrorCodes.OperationAborted);
				}
			}else{
				throw new NotFoundException(ErrorCodes.NoSuchContainer);
			}
			
			//更新容器元数据文件中的容器状态
			metafile.setStatus(ContainerStatus.Releasing.getValue());
			local.updateMetaContainer(metafile.getUuid(), metafile);
			
			//如果存在缓存，则更新缓存状态。
			if(cache != null){
				cache.setStatus(ContainerStatus.Releasing.getValue());
				cache_remote.updateCache(name, cache);
			}else{
//				TODO 缓存不存在，添加到缓存,可忽略
			}
			//TODO 容器存在，写入删除容器任务到临时任务表中
		}else if(MODE == 4){	//元数据使用独立存储，缓存存在多台缓存服务器中，均与执行服务器分离。
			Node node = KetamaNodeLocator.getCacheLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			MetaContainer metafile = null;
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
				if(cache != null){
					if(cache.getStatus() != ContainerStatus.Working.getValue()){
						//只有容器状态为正常时，才能进行容器的删除，否则返回409.冲突
						throw new ForbiddenException(ErrorCodes.OperationAborted);
					}
				}
				
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				metafile = local.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}

			if(metafile != null){
				if(metafile.getStatus() != ContainerStatus.Working.getValue()){
					throw new ForbiddenException(ErrorCodes.OperationAborted);
				}
			}else{
				throw new NotFoundException(ErrorCodes.NoSuchContainer);
			}
			
			//更新容器元数据文件中的容器状态
			metafile.setStatus(ContainerStatus.Releasing.getValue());
			local.updateMetaContainer(metafile.getUuid(), metafile);
			
			//如果存在缓存，则更新缓存状态。
			if(cache != null){
				cache.setStatus(ContainerStatus.Releasing.getValue());
				cache_remote.updateCache(name, cache);
			}else{
//				TODO 缓存不存在，添加到缓存,可忽略
			}
			//TODO 容器存在，写入删除容器任务到临时任务表中
		}else{
			//TODO 系统配置有错误，告警，并生成日志
			throw new InternalException(ErrorCodes.InternalError);
		}
	}
	
	public void setAccessControlPolicy(String name, AccessControlList acl){
		//检查参数
		if(name == null || name.trim().length() < 1){
			throw new BadRequestException(ErrorCodes.InvalidArgument);
		}
		if(acl == null || acl.getGrants().isEmpty()){
			return;
		}
//		}else{
//			 for (Map.Entry<String, Permission> m : acl.entrySet()) {
//				 if(!m.getValue().toString().matches("(R|W|D){1,3}")){
//					 throw new BusinessException(ErrorCodes.InvalidArgument);
//				 }
//			 }
//		}
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");

		ContainerCache cache = null;
		if(MODE == 0){			//表示单机版
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
//				local = new ContainerBean();
				local.setAccessControlPolicy(name, acl, this.principal);
			} catch (NamingException e1) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 1){	//缓存与元数据分散到执行服务器集群上
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				remote.setAccessControlPolicy(name, acl, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 2){	//独立缓存集群，元数据分散在执行服务器的本地磁盘。
			Node cache_node = KetamaNodeLocator.getCacheLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", cache_node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
			
			if(cache != null){
				if(cache.getStatus() != ContainerStatus.Working.getValue()){
					//只有容器状态为正常时，才能进行容器的删除，否则返回409.冲突
					throw new ForbiddenException(ErrorCodes.OperationAborted);
				}
			}
			
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			MetaContainer metafile = null;
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				metafile = remote.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
			if(metafile != null){
				if(metafile.getStatus() != ContainerStatus.Working.getValue()){
					throw new ForbiddenException(ErrorCodes.OperationAborted);
				}
			}else{
				throw new NotFoundException(ErrorCodes.NoSuchContainer);
			}			
			
			//更新容器元数据文件中的容器ACL属性
			metafile.setAccessControlPolicy(acl);
			remote.updateMetaContainer(metafile.getUuid(), metafile);
			
			//如果存在缓存，则更新缓存状态。
			if(cache != null){
				cache.setAccessControlPolicy(acl);
				cache_remote.updateCache(name, cache);
			}else{
//				TODO 缓存不存在，添加到缓存
			}
		}else if(MODE == 3){	//元数据使用独立共享存储，缓存分散到各个执行服务器集群
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			MetaContainer metafile = null;
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
				if(cache != null){
					if(cache.getStatus() != ContainerStatus.Working.getValue()){
						//只有容器状态为正常时，才能进行容器的删除，否则返回409.冲突
						throw new ForbiddenException(ErrorCodes.OperationAborted);
					}
				}
				
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				metafile = local.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}

			if(metafile != null){
				if(metafile.getStatus() != ContainerStatus.Working.getValue()){
					throw new ForbiddenException(ErrorCodes.OperationAborted);
				}
			}else{
				throw new NotFoundException(ErrorCodes.NoSuchContainer);
			}
			
			//更新容器元数据文件中的容器状态
			metafile.setAccessControlPolicy(acl);
			local.updateMetaContainer(metafile.getUuid(), metafile);
			
			//如果存在缓存，则更新缓存状态。
			if(cache != null){
				metafile.setAccessControlPolicy(acl);
				cache_remote.updateCache(name, cache);
			}else{
//				TODO 缓存不存在，添加到缓存
			}
		}else if(MODE == 4){	//元数据使用独立存储，缓存存在多台缓存服务器中，均与执行服务器分离。
			Node node = KetamaNodeLocator.getCacheLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			MetaContainer metafile = null;
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
				if(cache != null){
					if(cache.getStatus() != ContainerStatus.Working.getValue()){
						//只有容器状态为正常时，才能进行容器的删除，否则返回409.冲突
						throw new ForbiddenException(ErrorCodes.OperationAborted);
					}
				}
				
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				metafile = local.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}

			if(metafile != null){
				if(metafile.getStatus() != ContainerStatus.Working.getValue()){
					throw new ForbiddenException(ErrorCodes.OperationAborted);
				}
			}else{
				throw new NotFoundException(ErrorCodes.NoSuchContainer);
			}
			
			//更新容器元数据文件中的容器状态
			metafile.setAccessControlPolicy(acl);
			local.updateMetaContainer(metafile.getUuid(), metafile);
			
			//如果存在缓存，则更新缓存状态。
			if(cache != null){
				metafile.setAccessControlPolicy(acl);
				cache_remote.updateCache(name, cache);
			}else{
//				TODO 缓存不存在，添加到缓存
			}
		}else{
			//TODO 系统配置有错误，告警，并生成日志
			throw new InternalException(ErrorCodes.InternalError);
		}
	}
	
	/**
	 * 获得容器的ACL属性
	 * @param container 容器名
	 * @return
	 */
	public Map<String, String> getAccessControlList(String name){
		//检查参数
		if(name == null || name.trim().length() < 1){
			throw new BusinessException(ErrorCodes.InvalidArgument);
		}
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
		
		if(MODE == 0){			//表示单机版
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
//				local = new ContainerBean();
				return local.getAccessControlList(name, this.principal);
			} catch (NamingException e1) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 1){	//缓存与元数据分散到执行服务器集群上
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				return remote.getAccessControlList(name, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}		
		}else if(MODE == 2){	//独立缓存集群，元数据分散在执行服务器的本地磁盘。
			ContainerCache cache = null;
			Node cache_node = KetamaNodeLocator.getCacheLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", cache_node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
			//检查缓存
			if(cache != null){
				Map<String, String> aclMap = cache.getAccessControlList();
				return aclMap;
			}
			//检查元数据
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				MetaContainer metafile = remote.getMetaContainer(name);
				if(metafile == null){
					throw new NotFoundException(ErrorCodes.NoSuchContainer);
				}
				return metafile.getAccessControlList();
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}			
		}else if(MODE == 3){	//元数据使用独立共享存储，缓存分散到各个执行服务器集群
			ContainerCache cache = null;
			Node cache_node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", cache_node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
			//检查缓存
			if(cache != null){
				Map<String, String> aclMap = cache.getAccessControlList();
				return aclMap;
			}
			//检查元数据
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				MetaContainer metafile = local.getMetaContainer(name);
				if(metafile == null){
					throw new NotFoundException(ErrorCodes.NoSuchContainer);
				}
				return metafile.getAccessControlList();
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}	
		}else if(MODE == 4){	//元数据使用独立存储，缓存存在多台缓存服务器中，均与执行服务器分离。
			ContainerCache cache = null;
			Node cache_node = KetamaNodeLocator.getCacheLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", cache_node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				cache_remote = (CacheOperation)ctx.lookup("CacheBean/remote");
				cache = (ContainerCache)cache_remote.getCache(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
			//检查缓存
			if(cache != null){
				Map<String, String> aclMap = cache.getAccessControlList();
				return aclMap;
			}
			//检查元数据
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				MetaContainer metafile = local.getMetaContainer(name);
				if(metafile == null){
					throw new NotFoundException(ErrorCodes.NoSuchContainer);
				}
				return metafile.getAccessControlList();
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else{
			//TODO 系统配置有错误，告警，并生成日志
			throw new InternalException(ErrorCodes.InternalError);
		}
	}
	
	/**
	 * 获得容器的属性，属性不放入缓存
	 * @param name
	 * @param withMetadata
	 * @return
	 */
	public ContainerProperties getProperties(String name, boolean withMetadata){
		//检查参数
		if(name == null || name.trim().length() < 1){
			throw new BusinessException(ErrorCodes.InvalidArgument);
		}
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
		
		if(MODE == 0){			//表示单机版
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getProperties(name, withMetadata, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}			
		}else if(MODE == 1){	//缓存与元数据分散到执行服务器集群上
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				return remote.getProperties(name, withMetadata, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 2){	//独立缓存集群，元数据分散在执行服务器的本地磁盘。
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				return remote.getProperties(name, withMetadata, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 3){	//元数据使用独立共享存储，缓存分散到各个执行服务器集群
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getProperties(name, withMetadata, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 4){	//元数据使用独立存储，缓存存在多台缓存服务器中，均与执行服务器分离。
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getProperties(name, withMetadata, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else{
			//TODO 系统配置有错误，告警，并生成日志
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	public void setMetadata(String name, Map<String, String> meta){
		//检查参数
		if(name == null || name.trim().length() < 1){
			throw new InternalException(ErrorCodes.InvalidArgument);
		}
		
		if(meta == null || meta.size() == 0){
			return;
		}
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
		
		if(MODE == 0){			//表示单机版
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				local.setUserMetadata(name, meta, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 1){	//缓存与元数据分散到执行服务器集群上
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				remote.setUserMetadata(name, meta, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 2){	//独立缓存集群，元数据分散在执行服务器的本地磁盘。
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				remote.setUserMetadata(name, meta, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}			
		}else if(MODE == 3){	//元数据使用独立共享存储，缓存分散到各个执行服务器集群	
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				local.setUserMetadata(name, meta, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 4){	//元数据使用独立存储，缓存存在多台缓存服务器中，均与执行服务器分离。
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				local.setUserMetadata(name, meta, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else{
			//TODO 系统配置有错误，告警，并生成日志
			throw new InternalException(ErrorCodes.InternalError);
		}
	}

	public Map<String, String> getMetadata(String name) {
		//检查参数
		if(name == null || name.trim().length() < 1){
			throw new BusinessException(ErrorCodes.InvalidArgument);
		}
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
		
		if(MODE == 0){			//表示单机版
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getUserMetadata(name, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 1){	//缓存与元数据分散到执行服务器集群上
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				return remote.getUserMetadata(name, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}		
		}else if(MODE == 2){	//独立缓存集群，元数据分散在执行服务器的本地磁盘。
			//同1
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				return remote.getUserMetadata(name, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}			
		}else if(MODE == 3){	//元数据使用独立共享存储，缓存分散到各个执行服务器集群
			try { //同4
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getUserMetadata(name, this.principal);
			} catch (NamingException e) {
				throw new BusinessException(ErrorCodes.InternalError);
			}
		}else if(MODE == 4){	//元数据使用独立存储，缓存存在多台缓存服务器中，均与执行服务器分离。
			try {//同3
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getUserMetadata(name, this.principal);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else{
			//TODO 系统配置有错误，告警，并生成日志
			throw new BusinessException(ErrorCodes.InternalError);
		}
	}
	
	public MetaContainer getMetaContainer(String name){
		//检查参数
		if(name == null || name.trim().length() < 1){
			throw new InternalException(ErrorCodes.InvalidArgument);
		}
		
		Properties pros = new Properties();
		pros.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
		
		if(MODE == 0){			//表示单机版
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}		
		}else if(MODE == 1){	//缓存与元数据分散到执行服务器集群上
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				return remote.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}		
		}else if(MODE == 2){	//独立缓存集群，元数据分散在执行服务器的本地磁盘。
			Node node = KetamaNodeLocator.getLocator().getPrimary(name);
			pros.setProperty("java.naming.provider.url", node.getHost() + ":" + "1099");
			try {
				ctx = new InitialContext(pros);
				remote = (ContainerOperation)ctx.lookup("ContainerBean/remote");
				return remote.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}			
		}else if(MODE == 3){	//元数据使用独立共享存储，缓存分散到各个执行服务器集群
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else if(MODE == 4){	//元数据使用独立存储，缓存存在多台缓存服务器中，均与执行服务器分离。
			try {
				ctx = new InitialContext();
				local = (LocalContainerOperation)ctx.lookup("ContainerBean/local");
				return local.getMetaContainer(name);
			} catch (NamingException e) {
				throw new InternalException(ErrorCodes.InternalError);
			}
		}else{
			//TODO 系统配置有错误，告警，并生成日志
			throw new InternalException(ErrorCodes.InternalError);
		}
	}
}
